/**
 * Copyright (c) 2018 软唐 All rights reserved.
 * <p>
 * https://www.softtown.cn
 * <p>
 * 版权所有，侵权必究！
 */

package com.softtown.modules.sys.controller;

import com.softtown.common.annotation.LogOperation;
import com.softtown.common.exception.ErrorCode;
import com.softtown.common.regularUtils.RegularUtils;
import com.softtown.common.utils.ConvertUtils;
import com.softtown.common.utils.Result;
import com.softtown.common.validator.AssertUtils;
import com.softtown.common.validator.ValidatorUtils;
import com.softtown.common.validator.group.AddGroup;
import com.softtown.common.validator.group.DefaultGroup;
import com.softtown.common.validator.group.UpdateGroup;
import com.softtown.modules.message.entity.SysEmailContentEntity;
import com.softtown.modules.message.service.SysEmailContentService;
import com.softtown.modules.security.entity.SysSmsContentEntity;
import com.softtown.modules.security.service.SysSmsContentService;
import com.softtown.modules.sys.dto.*;
import com.softtown.modules.security.password.PasswordUtils;
import com.softtown.modules.security.user.SecurityUser;
import com.softtown.modules.security.user.UserDetail;
import com.softtown.modules.sys.entity.SysNoticeEntity;
import com.softtown.modules.sys.entity.SysUserEntity;
import com.softtown.modules.sys.service.SysParamsService;
import com.softtown.modules.sys.service.SysUserService;
import com.softtown.modules.sys.vo.SysUserVO;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import javax.annotation.Resource;
import net.sf.json.JSONObject;
import org.apache.shiro.authz.annotation.RequiresPermissions;
import org.springframework.web.bind.annotation.*;

import java.util.Arrays;
import java.util.Calendar;
import java.util.List;

/**
 * 用户管理
 *
 * @author Ding Ya Yong
 */
@RestController
@RequestMapping("/sys/user")
@Api(tags = "用户管理")
public class SysUserController {

    @Resource
    private SysUserService sysUserService;

    @Resource
    private SysSmsContentService sysSmsContentService;

    @Resource
    private SysEmailContentService sysEmailContentService;

    @Resource
    private SysParamsService sysParamsService;

    private static final String CLOUD_STORAGE__SERVICE_IS_USABLE = "STORAGE__SERVICE_IS_USABLE";

    private static final String YES = "Y";

    @GetMapping("info")
    @ApiOperation("登录用户信息")
    @LogOperation("登录用户信息")
    public Result<SysUserDTO> info() {
        SysUserDTO data = ConvertUtils.sourceToTarget(SecurityUser.getUser(), SysUserDTO.class);
        return new Result<SysUserDTO>().ok(data);
    }

    @PostMapping("findNotice")
    @ApiOperation("获取公告")
    @LogOperation("获取公告")
    public Result<SysNoticeEntity> findNotice() {
        SysNoticeEntity data = sysUserService.findNotice();
        return new Result<SysNoticeEntity>().ok(data);
    }

    /**
     * 密码修改
     *
     * @param dto
     * @return
     * @author Dingyayong
     * @date 2019/5/29 9:57
     */
    @PutMapping("password")
    @ApiOperation("修改密码")
    @LogOperation("修改密码")
    public Result password(@RequestBody PasswordDTO dto) {
        //效验数据
        ValidatorUtils.validateEntity(dto);

        UserDetail user = SecurityUser.getUser();

        Result result = new Result<>();
        //原密码不正确
        if (!PasswordUtils.matches(dto.getPassword(), user.getPassword())) {
            return result.error(ErrorCode.PASSWORD_ERROR);
        }
        if (!RegularUtils.ispwd(dto.getNewPassword())) {
            return result.error(ErrorCode.PWD_ERROR);
        }
        sysUserService.updatePassword(user.getId(), dto.getNewPassword());

        return result;
    }

    @PostMapping
    @ApiOperation("保存")
    @LogOperation("保存")
    @RequiresPermissions("sys:user:save")
    public Result save(@RequestBody SysUserDTO dto) {
        //效验数据
        ValidatorUtils.validateEntity(dto, AddGroup.class, DefaultGroup.class);

        sysUserService.save(dto);

        return new Result<>();
    }


    @PutMapping
    @ApiOperation("修改")
    @LogOperation("修改")
    @RequiresPermissions("sys:user:update")
    public Result update(@RequestBody SysUserDTO dto) {
        //效验数据
        ValidatorUtils.validateEntity(dto, UpdateGroup.class, DefaultGroup.class);

        sysUserService.update(dto);

        return new Result<>();
    }

    @DeleteMapping
    @ApiOperation("删除")
    @LogOperation("删除")
    @RequiresPermissions("sys:user:delete")
    public Result delete(@RequestBody Long[] ids) {
        //效验数据
        AssertUtils.isArrayEmpty(ids, "id");

        sysUserService.deleteBatchIds(Arrays.asList(ids));

        return new Result<>();
    }


    /**
     * saas用户注册
     *
     * @param registDTO
     * @return
     * @author Dingyayong
     * @date 2019/5/29 9:56
     */
    @PostMapping("register")
    @ApiOperation(value = "注册")
    @LogOperation(value = "注册")
    public Result register(@RequestBody RegistDTO registDTO) {
        SysUserDTO sysUserDTO = sysUserService.getByUsername(registDTO.getUsername());
        Result result = new Result<>();
        if (sysUserDTO != null) {
            return result.error(ErrorCode.USERNAME_EXISTS);
        }
        SysUserDTO dto = sysUserService.getByMobile(registDTO.getMobile());
        if (dto != null) {
            return result.error(ErrorCode.MOBILE_EXISTS);
        }
        if (!RegularUtils.ispwd(registDTO.getPassword())) {
            return result.error(ErrorCode.PWD_ERROR);
        }
        if (!registDTO.getPassword().equals(registDTO.getNewpwd())) {
            return result.error(ErrorCode.PASSWORD_SAME_ERROR);
        }
        SysSmsContentEntity sysSmsContentEntity = sysSmsContentService.getByMobile(registDTO.getMobile());
        if (!sysSmsContentEntity.getSmsCode().equals(registDTO.getSmscode())) {
            return result.error(ErrorCode.CAPTCHA_ERROR);
        } else if (Calendar.getInstance().getTime().after(sysSmsContentEntity.getSmsExpiresAt())) {
            return result.error(ErrorCode.SMSCODE_ERROR);
        }

        sysUserService.register(registDTO);
        return result;
    }

    @PostMapping("getUserInfo")
    @ApiOperation("获取用户")
    @LogOperation("获取用户")
    public Result<SysUserVO> getUserInfo(@RequestBody String userId) {
        String id = JSONObject.fromObject(userId).get("userId").toString();
        SysUserEntity sysUserEntity = sysUserService.getByUserId(Long.valueOf(id));
        SysUserVO sysUserVO = ConvertUtils.sourceToTarget(sysUserEntity, SysUserVO.class);
        return new Result<SysUserVO>().ok(sysUserVO);
    }

    /**
     * @param @param [sysUserMobileDTO]
     * @return @return com.softtown.common.utils.Result
     * @throws
     * @Title: unbundlingMobileNumber
     * @Description: 用户解绑手机号
     * @author fuming
     * @date 2019/7/10 22:09
     */
    @PostMapping("unbundlingMobileNumber")
    @ApiOperation("解绑手机号")
    @LogOperation("解绑手机号")
    public Result unbundlingMobileNumber(@RequestBody SysUserMobileDTO sysUserMobileDTO) {
        //效验数据
        ValidatorUtils.validateEntity(sysUserMobileDTO, UpdateGroup.class);

        Result result = new Result<>();
        if (!RegularUtils.isMobile(sysUserMobileDTO.getNewMobile())) {
            return result.error(ErrorCode.INCORRECT_NEW_MOBILE_FORMAT);
        }
        if (!RegularUtils.isNum(sysUserMobileDTO.getNewSmsCode())) {
            return result.error(ErrorCode.INCORRECT_NEW_CAPTCHA_FORMAT);
        }

        SysSmsContentEntity newSmsContent = sysSmsContentService.getByMobile(sysUserMobileDTO.getNewMobile());
        if (!sysUserMobileDTO.getNewSmsCode().equals(newSmsContent.getSmsCode())) {
            return result.error(ErrorCode.NEW_CAPTCHA_ERROR);
        }
        if (Calendar.getInstance().getTime().after(newSmsContent.getSmsExpiresAt())) {
            return result.error(ErrorCode.NEW_CODE_ERROR);
        }
        sysUserService.updateMobileNumber(sysUserMobileDTO);
        return result;
    }

    /**
     * @param @param [sysUserEmailDTO]
     * @return @return com.softtown.common.utils.Result
     * @throws
     * @Title: unbundlingEmail
     * @Description: 用户解绑邮箱
     * @author fuming
     * @date 2019/7/12 19:31
     */
    @PostMapping("unbundlingEmail")
    @ApiOperation("解绑邮箱")
    @LogOperation("解绑邮箱")
    public Result unbundlingEmail(@RequestBody SysUserEmailDTO sysUserEmailDTO) {
        //效验数据
        ValidatorUtils.validateEntity(sysUserEmailDTO, UpdateGroup.class);

        Result result = new Result<>();
        if (!RegularUtils.isEmail(sysUserEmailDTO.getNewEmail())) {
            return result.error(ErrorCode.INCORRECT_NEW_EMAIL_FORMAT);
        }
        if (!RegularUtils.isNum(sysUserEmailDTO.getNewEmailCode())) {
            return result.error(ErrorCode.INCORRECT_NEW_CAPTCHA_FORMAT);
        }

        SysEmailContentEntity newEmailContent = sysEmailContentService.getByEmail(sysUserEmailDTO.getNewEmail());
        if (!sysUserEmailDTO.getNewEmailCode().equals(newEmailContent.getEmailCode())) {
            return result.error(ErrorCode.NEW_CAPTCHA_ERROR);
        }
        if (Calendar.getInstance().getTime().after(newEmailContent.getEmailExpiresAt())) {
            return result.error(ErrorCode.NEW_CODE_ERROR);
        }
        sysUserService.updateEmail(sysUserEmailDTO);
        return result;
    }

    /**
     * @param @param [sysUserDTO]
     * @return @return com.softtown.common.utils.Result
     * @throws
     * @Title: updateUserInfo
     * @Description: 用户个人信息修改
     * @author fuming
     * @date 2019/7/12 19:32
     */
    @PostMapping("updateUserInfo")
    @ApiOperation("个人信息修改")
    @LogOperation("个人信息修改")
    public Result updateUserInfo(@RequestBody SysUserDTO sysUserDTO) {
        //效验数据
        String flag = sysParamsService.getValue(CLOUD_STORAGE__SERVICE_IS_USABLE);
        Result result = new Result<>();
        if (!flag.equals(YES)) {
            return result.error(ErrorCode.STORAGE_SERVICE_ERROR);
        }
        if(sysUserDTO.getNickname() !=null){
            if (RegularUtils.isRealName(sysUserDTO.getNickname()) || RegularUtils.isNum(sysUserDTO.getNickname())) {
                return result.error(ErrorCode.INCORRECT_REAL_NAME_FORMAT);
            }
        }

        if (sysUserDTO.getEmail() != null) {
            if (!RegularUtils.isEmail(sysUserDTO.getEmail())) {
                return result.error(ErrorCode.INCORRECT_EMAIL_FORMAT);
            }
            List<SysUserVO> userInfos = sysUserService.getSysUserInfos();
            SysUserEntity userEntity = sysUserService.getByUserId(sysUserDTO.getId());
            for (SysUserVO user:userInfos) {
                String email = user.getEmail();
                if (sysUserDTO.getEmail().equals(email) && !sysUserDTO.getEmail().equals(userEntity.getEmail())) {
                    return result.error(ErrorCode.EMAIL_EXISTS);
                }
                if (sysUserDTO.getMobile().equals(user.getMobile()) && !sysUserDTO.getMobile().equals(userEntity.getMobile())) {
                    return result.error(ErrorCode.MOBILE_EXISTS);
                }
            }
        }
        sysUserService.updatePersonalInfo(sysUserDTO);
        return new Result();
    }

    @PostMapping("resetPassword")
    @ApiOperation("管理员重置密码")
    @LogOperation("管理员重置密码")
    public Result resetPassword(@RequestBody SysUserDTO sysUserDTO) {
        Result result = new Result<>();

        if (!RegularUtils.ispwd(sysUserDTO.getNewPassword())) {
            return result.error(ErrorCode.PWD_ERROR);
        }
        if (!sysUserDTO.getNewPassword().equals(sysUserDTO.getComfirmPassword())) {
            return result.error(ErrorCode.PASSWORD_SAME_ERROR);
        }
        sysUserService.upadteUserInfoBySysUserDTO(sysUserDTO);
        return result;
    }

    /**
     * 获取所有系统用户的邮箱账号
     *
     * @param
     * @return com.softtown.common.utils.Result<java.util.List < java.lang.String>>
     * @Author fuming
     * @Date 2020/2/6 13:56
     */
    @PostMapping("getSysUserEmailList")
    @ApiOperation("查询所有系统用户的邮箱账号")
    @LogOperation("查询所有系统用户的邮箱账号")
    public Result<List<String>> getSysUserEmailList() {
        List<String> userEmailList = sysUserService.selectSysUserEmailList();
        return new Result<List<String>>().ok(userEmailList);
    }

    @PostMapping("changeUserLanguage")
    @ApiOperation("切换语言时，更改用户语言")
    @LogOperation("切换语言时，更改用户语言")
    public Result changeUserLanguage(@RequestBody SysUserDTO sysUserDTO) {
        sysUserService.changeUserLanguage(sysUserDTO.getLanguage());
        return new Result<>();
    }
}